---
title: Effects
---

Effects can be used to execute side effects (actions, http requests and other operations) upon action events. First, install the package:

```bash
npm i @datorama/akita-ng-effects
```

Next, to register effects, simply run `AkitaNgEffects.forRoot()` and register the effect classes:

```ts title="app.module.ts"
import { AkitaNgEffectsModule } from '@datorama/akita-ng-effects';
import { NavigationEffects } from './path/to/effects';

// Only use .forRoot() once in your base module.
@NgModule({
  imports: [CommonModule, AkitaNgEffectsModule.forRoot([NavigationEffects])],
})
export class AppModule {}
```

```ts title="product.module.ts"
import { AkitaNgEffectsModule } from '@datorama/akita-ng-effects';
import { ProductEffects } from './path/to/effects';

// Use .forFeature() on any feature module
@NgModule({
  imports: [CommonModule, AkitaNgEffectsModule.forFeature([ProductEffects])],
})
export class FeatureModule {}
```

## Setup Actions

An action always holds a type property and an optional payload.

```ts title="navigation.actions.ts"
import { createAction } from '@datorama/akita-ng-effects';

export const loadMainNavigation = createAction('[Navigation] Load Main Navigation');

export const loadMainNavigationSuccess = createAction(
  '[Navigation] Load Main Navigation Success',
   props<{ mainNav: { id: number; path: string } }>()
);
```

## Setup Effects

You can use the actions to act upon any action event:

```ts title="navigation.effect.ts"
import { Actions } from '@datorama/akita-ng-effects';

@Injectable()
export class NavigationEffects {
  constructor(
    private actions$: Actions,
    private navigationService: NavigationService,
  ) {}

  loadMainNavigation$ = createEffect(() =>
    this.actions$.pipe(
      ofType(loadMainNavigation),
      switchMap((_) =>
         this.navigationService.loadMainNavigation().pipe(
           map((mainNav) => loadMainNavigationSuccess({ mainNav }))
        )
      )
    ), { dispatch: true }
  );

  // Or use the decorator
  @Effect()
  loadMainNavigationSuccess$ = this.actions$.pipe(
    ofType(loadMainNavigationSuccess),
    map(({ mainNav }) => this.navigationService.updateNavigationTree(mainNav)),
    tap((mainRoutes) => this.store.updateNavigation(mainRoutes))
  );
}
```

#### The parameter `dispatch`
This parameter dictates if the effect can dispatch an action. Set `true` if you want the effect to dispatch an action. Set to `false` or omit if the effect should not dispatch any action.

### Possible use case

This is one possible use case for an action inside a guard to initialize fetching of a navigation.

You can also use them in components in order to fetch data.

```ts title="init-route.guard.ts"
@Injectable({
  providedIn: 'root',
})
export class InitRouterGuard implements CanActivate {
  constructor(private actions: Actions, private navigationQuery: NavigationQuery) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
    return this.navigationQuery.isNavInitialized$.pipe(
      tap((isInit) => {
        if (!isInit) this.actions.dispatch(loadMainNavigation());
      }),
      filter((isInit) => isInit),
      map((_) => true)
    );
  }
}
```
